def confirm(msg)
  puts msg
  STDIN.gets.strip == 'yes'
end

def wipe_data(project_name, version_number, force=false)
  unless force
    msg  = " /!\\ WARNING /!\\ THIS OPERATION WILL WIPE OUT EVERYTHING FROM THE JSDOC-RAILS TABLES.\n"
    msg += " /!\\ WARNING /!\\ To skip this step specify NOWIPE=true when calling this task.\n"
    msg += " /!\\ WARNING /!\\ If you're sure you want to continue, please type 'yes'."
  end

  unless force or confirm(msg)
    puts "Data wipe cancelled"
    return false 
  end

  project = Jsdoc::Project.where(['name = :name OR slug = :name', {:name => project_name}]).first
  unless project.present?
    puts "No project found named '#{project_name}', so nothing to delete"
    return true
  end

  version = project.versions.where(:version_number => version_number).first
  unless version.present?
    puts "No version found named '#{version_number}', so nothing to delete"
    return true
  end
    
  puts "Deleting everything for: #{project.name} (#{version.version_number})"
  version.symbols.destroy_all

  return true
end

def output_jsdocs(src, dst, project_name, version_number)
  output_dir = File.dirname(dst)
  output_file = File.basename(dst)
  jsdoc_path = File.join(File.dirname(__FILE__), '../../jsdoc-toolkit')
  template_path = File.join(jsdoc_path, 'templates', 'jsdoc-rails')
  
  project_slug = project_name.gsub(/[^0-9a-zA-Z\-_]+/, '-').gsub(/-+/, '-').gsub(/^-|-$/, '').downcase

  puts "Reading from: #{ENV['SRC']}"
  puts "Outputing to: #{File.join(output_dir, output_file)}"

  system(%Q(cd "#{src.gsub('"', '\\"')}"; java -jar "#{jsdoc_path}/jsrun.jar" "#{jsdoc_path}/app/run.js" -r=100 -a -d="#{output_dir}" -D="outputFile:#{output_file}" -D="projectName:#{project_name}" -D="projectSlug:#{project_slug}" -D="versionNumber:#{version_number}" -t=#{template_path} -- *))
  puts "Generated data"
end

namespace :jsdoc do
  desc "Write a Ruby script containing all the JSDoc definitions which can be loaded directly into Rails. Specify with SRC=/path/to/javascript/, OUTPUT=db/jsdoc-data.rb"
  task :output do
    output = ENV['OUTPUT'] || 'db/jsdoc-data.rb'
    output = File.join(Dir.pwd, output) unless output[0..0] == '/'
    src = ENV['SRC']
    project = ENV['PROJECT']
    version = ENV['VERSION']

    if src.blank?
      puts "You must specify the SRC variable pointing to the location of your javascript code"
      return 1
    end

    output_jsdocs(src, output, project, version)
  end
end

namespace :jsdoc do
  desc "Load a Ruby script containing JSDoc data, as generated by 'rake jsdoc:output'. Specify with SRC=db/jsdoc-data.rb, NOWIPE=false"
  task :load => :environment do
    src = ENV['SRC'] || 'db/jsdoc-data.rb'
    project = ENV['PROJECT']
    version = ENV['VERSION']
    force = ENV['FORCEWIPE'].present? and ENV['FORCEWIPE'][0..0].downcase == 't'

    unless ENV['NOWIPE'].present? and ENV['NOWIPE'][0..0].downcase == 't'
      unless wipe_data(project, version, force)
        puts "Data load cancelled"
        exit
      end
    end
    load(src)
  end
end

namespace :jsdoc do
  desc "Load all the JSDoc data from your Javascript source. Effectivly the same as running jsdoc:output then jsdoc:load. Specify with SRC=/path/to/javascript/, NOWIPE=false"
  task :import => :environment do
    src = ENV['SRC']
    project = ENV['PROJECT']
    version = ENV['VERSION']
    force = ENV['FORCEWIPE'].present? and ENV['FORCEWIPE'][0..0].downcase == 't'

    if src.blank?
      puts "You must specify the SRC variable pointing to the location of your javascript code"
      return 1
    end

    unless ENV['NOWIPE'].present? and ENV['NOWIPE'][0..0].downcase == 'f'
      unless wipe_data(project, version, force)
        puts "Data load cancelled"
        exit
      end
    end

    tmpfile = Tempfile.new('jsdoc-rails')
    output_jsdocs(src, tmpfile.path, project, version)
    load(tmpfile.path)
    tmpfile.close
  end
end
